#include"Index.hpp"
#include"util.hpp"
#include<algorithm>
#include<jsoncpp/json/json.h>

namespace ns_searcher
{
    class Searcher
    {
    public:
        Searcher()
        {}

        void InitSearcher(const string& path)
        {
            //1.获取或创建index对象
            _index=ns_index::Index::GetInstance();

            cout<<"开始初始化排序索引..."<<endl;

            //2.根据源文档路径，初始化index的排序索引（正排索引和倒排索引）
            _index->BuildIndex(path);

            cout<<"排序索引建立成功..."<<endl;
        }

        void Search(const string& statement,string& json_info)
        {
            //1.[分词]：对我们的statement进行按照searcher的要求进行分词
            vector<string> words;
            ns_util::StringUtil::CutString(statement,words);

            //2.[触发]：就是根据分词的各个“词”，进行倒排查找，返回一个list，里面存放所有含有key的文档的一些属性
            ns_index::InvertedList invertedlist_all;
            for(auto& key_word:words)
            {
                boost::to_lower(key_word);
                ns_index::InvertedList* invertedlist=_index->GetInvertedIndex(key_word);
                if(invertedlist==nullptr)
                    continue;
                //把statement语句的所有文档的所有obj信息全都放在一个“大拉链”里
                invertedlist_all.insert(invertedlist_all.end(),invertedlist->begin(),invertedlist->end());
            }
            //3.[合并排序]：汇总查找结果，按照相关性降序排序
            std::sort(invertedlist_all.begin(),invertedlist_all.end(),\
            [](ns_index::Inverted_Object& e1,ns_index::Inverted_Object& e2){return e1.weight>e2.weight;});
            //4.[构建]：根据查找出来的结果，构建json串
            Json::Value root;
            for(auto& inverted_obj:invertedlist_all)
            {
                Json::Value elem;
                elem["weight"]=inverted_obj.weight;

                ns_index::DocInfo* doc=_index->GetForwardIndex(inverted_obj.doc_id);
                if(doc==nullptr)continue;
                
                elem["title"]=doc->title;
                elem["describe"]=GetOutline(doc->content,inverted_obj.key_word);
                elem["url"]=doc->url;
                elem["ID"]=(int)doc->doc_id;

                root.append(elem);
            }
            Json::StyledWriter writer;
            json_info=writer.write(root);
        }
        
        ~Searcher()
        {}

    private:
        string GetOutline(const string& content,string key_word)
        {
            //1.确定摘要大小
            size_t prev_step=50,next_step=100;

            //2.确定key_word的位置,忽略key_word的大小写
            auto iter=std::search(content.begin(),content.end(),key_word.begin(),key_word.end(),\
            [](int x,int y)
            {
                return std::tolower(x)==std::tolower(y);
            });
            if(iter==content.end()) return "None";
            int pos=std::distance(content.begin(),iter);

            //3.给start和end赋值
            int start=0,end=content.size()-1;
            if(pos>start+prev_step)start=pos-prev_step;
            if(pos+next_step<end)end=pos+next_step;

            //4.截取内容
            if(start>=end)return "none";
            string ret=content.substr(start,end-start);//左闭右开
            return ret+"...";
        }
    private:    
        ns_index::Index* _index;
    };
}